package main

import (
	"fmt"
	"reflect"
)

func main() {
	//Go中的反射
	//反射
	//有时我们需要写一个函数，这个函数有能力统一处理各种值类型，而这些类型可能无法共享同一个接口，也可能布局未知，也有可能这个类型在我们设计函数时还不存在，这个时候我们就可以用到反射。
	//
	//空接口可以存储任意类型的变量，那我们如何知道这个空接口保存数据的类型是什么？ 值是什么呢？
	//
	//可以使用类型断言
	//可以使用反射实现，也就是在程序运行时动态的获取一个变量的类型信息和值信息。
	//把结构体序列化成json字符串，自定义结构体Tab标签的时候就用到了反射
	//
	//后面所说的ORM框架，底层就是用到了反射技术
	//
	//ORM：对象关系映射（Object Relational Mapping，简称 ORM）是通过使用描述对象和数据库之间的映射的元数据，将面向对象语言程序中的对象自动持久化到关系数据库中。Go可以实现的功能
	//反射可以在程序运行期间动态的获取变量的各种信息，比如变量的类型类别
	//如果是结构体，通过反射还可以获取结构体本身的信息，比如结构体的字段、结构体的方法。
	//通过反射，可以修改变量的值，可以调用关联的方法
	//Go语言中的变量是分为两部分的：
	//
	//类型信息：预先定义好的元信息。
	//值信息：程序运行过程中可动态变化的。
	//在Go语言的反射机制中，任何接口值都由是一个具体类型和具体类型的值两部分组成的。
	//
	//在Go语言中反射的相关功能由内置的reflect包提供，任意接口值在反射中都可以理解为由 reflect.Type 和 reflect.Value两部分组成，并且reflect包提供了reflect.TypeOf和reflect.ValueOf两个重要函数来获取任意对象的Value 和 Type
	//
	//reflect.TypeOf()获取任意值的类型对象
	//在Go 语言中，使用reflect.TypeOf（）函数可以接受任意interface}参数，可以获得任意值的类型对象（reflect.Type），程序通过类型对象可以访问任意值的类型信息。
	//通过反射获取空接口的类型
	reflectFun(10)
	reflectFun(10.01)
	reflectFun("abc")
	reflectFun(true)
}

func reflectFun(x interface{}) {
	fmt.Println(reflect.TypeOf(x))
}
